#!/bin/bash

# shellcheck disable=SC2120

# Provide source directive to shellcheck.
# shellcheck source=meta-facebook/meta-yosemite4/recipes-phosphor/state/phosphor-state-manager/power-cmd
source /usr/libexec/phosphor-state-manager/power-cmd
# shellcheck source=meta-facebook/meta-yosemite4/recipes-yosemite4/plat-tool/files/yosemite4-common-functions
source /usr/libexec/yosemite4-common-functions

#IO 0:7 input port for showing slot 1:8 power status
#IO 8:16 output port for controlling slot 1:8 power status
CHASSIS_ID=$1
slot_power_control_lock="/run/slot_power_control_${CHASSIS_ID}.lock"
IO_EXP_P0_PWRGD_R_OUT=18
IO_EXP_SLOT_PWR_STATUS=$((CHASSIS_ID - 1))
IO_EXP_SLOT_PWR_CTRL=$((IO_EXP_SLOT_PWR_STATUS + 8))
IO_EXP_SLOT_12V_STATUS=$((CHASSIS_ID + 23))

GPIOCHIP_IO_EXP_SLOT_PWR_CTRL=$(basename "/sys/bus/i2c/devices/$SPIDER_BOARD_IO_EXP_BUS_NUM-00$IO_EXP_SLOT_PWR_CTRL_ADDR/"*gpiochip*)
GPIOCHIP_IO_EXP_SLOT_12V_STATUS_CTRL=$(basename "/sys/bus/i2c/devices/$MANAGEMENT_BOARD_IO_EXP_BUS_NUM-00$IO_EXP_SLED_PWR_CTRL_ADDR/"*gpiochip*)
GPIOCHIP_IO_EXP_HOST_POWER_STATUS=$(basename "/sys/bus/i2c/devices/$IO_EXP_SLOT_PWR_STATUS-0023/"*gpiochip*)

is_nuvoton_board="$(check_nuvoton_board)"

# Server 12v power on
chassis-power-on()
{
    if ! gpio_set "$GPIOCHIP_IO_EXP_SLOT_PWR_CTRL" "$IO_EXP_SLOT_PWR_CTRL"=0
    then
        msg="Failed to set chassis$1 power on"
        echo "${msg}"
        add_sel "${msg}"
    fi
    sleep 1

    # Check chassis status after doing 12V on
    chassis_status=$(get_ac_on_status "$GPIOCHIP_IO_EXP_SLOT_PWR_CTRL" "$IO_EXP_SLOT_PWR_STATUS")
    if [ "$chassis_status" == "$STATE_ON" ]
    then
        if [ -n "$is_nuvoton_board" ]
        then
            # inform management CPLD that the slot is 12V on
            if ! gpio_set "$GPIOCHIP_IO_EXP_SLOT_12V_STATUS_CTRL" "$IO_EXP_SLOT_12V_STATUS"=1
            then
                echo "Failed to inform management CPLD that chassis$1 is 12V on"
            fi
        fi

        # Wait for standby sensors to be ready
        sleep 2
        busctl set-property "$CHASSIS_BUS_NAME""$CHASSIS_ID" "$CHASSIS_OBJ_PATH""$CHASSIS_ID" "$CHASSIS_INTF_NAME" "$CHASSIS_PROPERTY_NAME" s "$CHASSIS_ON_PROPERTY"
        echo "Chassis$CHASSIS_ID is power on"
    else
        busctl set-property "$CHASSIS_BUS_NAME""$CHASSIS_ID" "$CHASSIS_OBJ_PATH""$CHASSIS_ID" "$CHASSIS_INTF_NAME" "$CHASSIS_PROPERTY_NAME" s "$CHASSIS_OFF_PROPERTY"
        msg="Failed to power on Chassis$CHASSIS_ID, Chassis$CHASSIS_ID is power off"
        echo "${msg}"
        add_sel "${msg}"
        exit 0;
    fi
}

msg="Execute chassis$CHASSIS_ID power on"
echo "${msg}"
add_sel "${msg}"

exec 300>"$slot_power_control_lock"
if ! flock -n 300 ; then
    chassis_status=$(gpio_get "$GPIOCHIP_IO_EXP_SLOT_PWR_CTRL" "$IO_EXP_SLOT_PWR_STATUS")
    if [ "$chassis_status" == "$STATE_ON" ]; then
        # Chassis already on (e.g. due to AC on), skip power on, do not record SEL
        msg="Chassis$1 is already on"
        echo "${msg}"
        add_sel "${msg}"
        exit 0
    else
        echo "Slot $CHASSIS_ID is currently running a power control operation, skipping."
        msg="Execute chassis$CHASSIS_ID power on fail, power control is operating"
        echo "${msg}"
        add_sel "${msg}"
        exit 1
    fi
fi

if ! chassis_status=$(gpio_get "$GPIOCHIP_IO_EXP_SLOT_PWR_CTRL" "$IO_EXP_SLOT_PWR_STATUS"); then
    echo "Failed to get chassis status"
    exit 1
fi

if [ "$chassis_status" == "$STATE_OFF" ]
then
    # Check if PRSNT_SB_SLOT{1~8}_N is exist, if not exist, continues power-on process
    if [ ! -f "/tmp/gpio/PRSNT_SB_SLOT${1}_N" ]; then
        echo "PRSNT_SB_SLOT${1}_N is not exist, continue power-on process"
    else
        slot_presence=$(cat /tmp/gpio/PRSNT_SB_SLOT"${1}"_N)
        if [ "$slot_presence" -ne 0 ]; then
            echo "Chassis$1 is not present, skip power-on process"
            exit 1
        fi
    fi

    chassis-power-on
    /usr/libexec/phosphor-state-manager/wait-until-mctp-connection-done "$CHASSIS_ID"
else
    msg="Chassis$1 is already on"
    echo "${msg}"
    add_sel "${msg}"
fi

host_status=$(gpio_get "$GPIOCHIP_IO_EXP_HOST_POWER_STATUS" "$IO_EXP_P0_PWRGD_R_OUT")
if [ "$host_status" != "$STATE_ON" ]
then
    systemctl restart "phosphor-discover-system-state@$CHASSIS_ID.service"
    echo "Power on Host$CHASSIS_ID"
fi
exit 0;
